package online.heycm.rbac.common.config.exception;

import online.heycm.platform.common.entity.exception.BizException;
import online.heycm.platform.common.entity.result.Result;
import online.heycm.platform.log.Logger;
import online.heycm.platform.log.LoggerManager;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Iterator;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @author hey
 * @version 1.0
 * @date 2024/1/12 15:13
 */
// @RestControllerAdvice
public class WebErrorHandler {
    private static final Logger log = LoggerManager.getLogger(WebErrorHandler.class);

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({Throwable.class})
    public Result error(Throwable e) {
        log.error("发生未知异常！", e);
        return Result.error(500, "服务器错误");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({Exception.class})
    public Result error(Exception e) {
        log.error("发生未知异常！", e);
        return Result.error(500, "服务器错误");
    }

    @ExceptionHandler({BizException.class})
    public Result error(BizException e) {
        return Result.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler({BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public Result handleValidatedException(Exception e) {
        String message;
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException)e;
            message = this.getParamError(ex.getBindingResult());
        } else if (e instanceof ConstraintViolationException) {
            ConstraintViolationException ex = (ConstraintViolationException)e;
            message = (String)ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("; "));
        } else if (e instanceof BindException) {
            BindException ex = (BindException)e;
            message = this.getParamError(ex.getBindingResult());
        } else {
            message = "参数错误";
        }

        return Result.error(400, message);
    }

    private String getParamError(BindingResult br) {
        List<FieldError> fieldErrors = br.getFieldErrors();
        if (CollectionUtils.isEmpty(fieldErrors)) {
            return "参数错误";
        } else {
            StringJoiner joiner = new StringJoiner(";");

            String field;
            String message;
            for(Iterator var4 = fieldErrors.iterator(); var4.hasNext(); joiner.add(field + ":" + message)) {
                FieldError fieldError = (FieldError)var4.next();
                field = fieldError.getField();
                message = fieldError.getDefaultMessage();
                if (message != null && message.contains("java.lang.NumberFormatException")) {
                    message = "参数类型异常";
                }
            }

            return joiner.toString();
        }
    }
}
